#include "imageBMP.h"
#include "Grille.h"
#include "Game.h"
#include <iostream>
#include <cmath>
#include <vector>

#include <GL/glu.h>


Game::Game(char *fichier,int _nbFantome){
	imageBMP image(fichier);
	grille = new Grille(&image);
	nbFantome=_nbFantome;
	init();
}

void Game::init(void){
	positionInitialFantome.x = 9;
	positionInitialFantome.y = 9;

	positionInitialPacman.x = 9;
	positionInitialPacman.y = 5;

	fantomes = new Fantome[nbFantome];
	for(int i=0; i<nbFantome; i++){

		fantomes[i].couleur[0]=rand()%8/4.0;	//r
		fantomes[i].couleur[1]=rand()%8/4.0;	//g
		fantomes[i].couleur[2]=rand()%8/4.0;	//b
		// case d'apparition des fantômes
		fantomes[i].pos.x = positionInitialFantome.x;
		fantomes[i].pos.y = positionInitialFantome.y;
		fantomes[i].direction = SOUTH;
		fantomes[i].oldPos.x = -1;
		fantomes[i].oldPos.y = -1;
		fantomes[i].mode = MODEF_NORMAL;
		fantomes[i].wait = i*400;
	}
	
	// Au début on commence avec 3 vies
	joueur.nbVie = 3;
	joueur.pos.x = positionInitialPacman.x;
	joueur.pos.y = positionInitialPacman.y;
	joueur.direction = WEST;
	joueur.mode = MODEJ_NORMAL;
	joueur.score = 0;
	grille->set(joueur.pos.x,joueur.pos.y,3);

	lose = false;
	begin = false;
}

void Game::afficheGrille(void){
	grille->afficheGrille();
}

void Game::play(void){
	if(begin){

		float delta = 0.1;
		for(int i=0; i<nbFantome; i++){
			if(fantomes[i].mode == MODEF_MANGE){
				if(fantomes[i].wait==0){
					fantomes[i].mode = MODEF_NORMAL;
					fantomes[i].pos.x = positionInitialFantome.x;
					fantomes[i].pos.y = positionInitialFantome.y;
				}else{
					fantomes[i].wait--;
				}
			}else if(fantomes[i].wait >0 ){
				fantomes[i].wait--;
			}else{
				int resFantome1 = getResMove(fantomes[i].direction,fantomes[i].pos);
				if(resFantome1!=1){

					if(resFantome1 == -1){
						if(fantomes[i].pos.x < 0)
							fantomes[i].pos.x = grille->getWidth();
						if(fantomes[i].pos.x > grille->getWidth())
							fantomes[i].pos.x = 0;
						if(fantomes[i].pos.y < 0)
							fantomes[i].pos.y = grille->getHeight();
						if(fantomes[i].pos.y > grille->getHeight())
							fantomes[i].pos.y = 0;
					}
					else{
						int posXReel = (int)floor(fantomes[i].pos.x*10);
						int posYReel = (int)floor(fantomes[i].pos.y*10);
						int posXCentre = ((int)(fantomes[i].pos.x))*10;
						int posYCentre = ((int)(fantomes[i].pos.y))*10;

						if(posXReel == posXCentre && posYReel == posYCentre && (fantomes[i].oldPos.x != posXCentre || fantomes[i].oldPos.y != posYCentre)){
							vector<Direction> dirPossible;
							if(getResMove(Direction::NORTH, fantomes[i].pos) != 1){
								if(fantomes[i].direction != Direction::SOUTH);
									dirPossible.push_back(Direction::NORTH);
							}
							if(getResMove(Direction::SOUTH, fantomes[i].pos) != 1){
								if(fantomes[i].direction != Direction::NORTH);
									dirPossible.push_back(Direction::SOUTH);
							}
							if(getResMove(Direction::EAST, fantomes[i].pos) != 1){
								if(fantomes[i].direction != Direction::WEST);
									dirPossible.push_back(Direction::EAST);
							}
							if(getResMove(Direction::WEST, fantomes[i].pos) != 1){
								if(fantomes[i].direction != Direction::EAST);
									dirPossible.push_back(Direction::WEST);
							}

							if(dirPossible.size()>2){
								printf("\t\taaaa -> (%d,%d) ; (%d,%d)\n", posXCentre, posYCentre, posXReel, posYReel);
								fantomes[i].direction = dirPossible[rand()%dirPossible.size()];
								fantomes[i].oldPos.x = posXCentre;
								fantomes[i].oldPos.y = posYCentre;
							}
						}
					}

					float coeff;
					if(joueur.mode == MODEJ_SUPERPACMAN)
						coeff = 3;
					else
						coeff = 1.5;
					
					fantomes[i].pos.x += getTx(fantomes[i].direction)*delta/coeff;
					fantomes[i].pos.y += getTy(fantomes[i].direction)*delta/coeff;
				} 
				else{
					fantomes[i].direction = (Direction) (rand()%4);
				}
			}

			if(((int)fantomes[i].pos.x==(int)joueur.pos.x) && ((int)fantomes[i].pos.y==(int)joueur.pos.y) && fantomes[i].mode != MODEF_MANGE){
				if(joueur.mode == MODEJ_SUPERPACMAN){
					fantomes[i].mode = MODEF_MANGE;
					fantomes[i].wait = 300;
				}else{
					lose = true;
				}
			}
		}

		
		joueur.timer--;
		if(joueur.timer<=0){
			joueur.mode = MODEJ_NORMAL;
		}

		int res = getResMove(joueur.direction,joueur.pos);
		if(lose){
			res=1;
		}
		//cout << res;
		//cout << joueur.pos.x << " " << joueur.pos.y << " # " << res << " (" << tx << "," << ty << ")" << endl;
		int tx,ty;

		if(res!=1 && res != -1){
			if(res==2){
				joueur.score += 10;
				joueur.mode = MODEJ_SUPERPACMAN;
				joueur.timer=500;
				cout << "+10" << endl;
			}
			if(res==0){
				joueur.score += 1;
				cout << "+1" << endl;
			}
		
			//if(res==5)
			//	grille->transporter(&joueur.pos.x,&joueur.pos.y);
		
			//grille->set(joueur.pos.x,joueur.pos.y,4); // vide
			// 
			if(joueur.direction == NORTH){
				tx = 0;
				ty = -1;
				grille->set(joueur.pos.x+tx,joueur.pos.y+ty+0.9,4);
			}else if(joueur.direction == SOUTH){
				tx = 0;
				ty = 1;
				grille->set(joueur.pos.x+tx,joueur.pos.y+ty,4);
			}else if(joueur.direction == EAST){
				tx = 1;
				ty = 0;
				grille->set(joueur.pos.x+tx,joueur.pos.y+ty,4);
			}else if(joueur.direction == WEST){
				tx = -1;
				ty = 0;
				grille->set(joueur.pos.x+tx+0.9,joueur.pos.y+ty,4);
			}


			joueur.pos.x += tx*delta;
			joueur.pos.y += ty*delta;
			if(joueur.direction == EAST || joueur.direction == WEST)
				joueur.pos.y=(int)joueur.pos.y;
			if(joueur.direction == NORTH || joueur.direction == SOUTH)
				joueur.pos.x=(int)joueur.pos.x;
		
			grille->set(joueur.pos.x,joueur.pos.y,3); // pacman

		}else if(res==-1){
				if(joueur.pos.x>=grille->getWidth()-1){
					joueur.pos.x = 0;
					//cout << "x=0;" << endl;
				}else if(joueur.pos.x<=0){
					joueur.pos.x = grille->getWidth()-1;
					//cout << "x=width-1;" << endl;
				}else if(joueur.pos.y>=grille->getHeight()-1){
					joueur.pos.y = 0;
					//cout << "y=0;" << endl;
				}else if(joueur.pos.y<=0){
					joueur.pos.y = grille->getHeight()-1;
					//cout << "y=height-1;" << endl;
				}
		}/*else{
			//joueur.pos.x=(int)joueur.pos.x;
			//joueur.pos.y=(int)joueur.pos.y;
			joueur.direction = OTHER;
		}*/

		//cout << joueur.score << endl;

	}
}


int Game::getResMove(Direction direction, Position pos){
	if(pos.x < 0 || pos.x > grille->getWidth() || pos.y < 0 || pos.y > grille->getHeight())
		return -1;
	
	int res;

	if(direction == NORTH){
		res = grille->get(pos.x,pos.y-0.1);
	}else if(direction == SOUTH){
		res = grille->get(pos.x,pos.y+1);
	}else if(direction == EAST){
		res = grille->get(pos.x+1,pos.y);
	}else if(direction == WEST){
		res = grille->get(pos.x-0.1,pos.y);
	}else{
		res=1;
	}
	return res;
}
int Game::getTy(Direction direction){
	if(direction == NORTH){
		return -1;
	}else if(direction == SOUTH){
		return 1;
	}else{
		return 0;
	}
}
int Game::getTx(Direction direction){
	if(direction == EAST){
		return 1;
	}else if(direction == WEST){
		return -1;
	}else{
		return 0;
	}
}

Grille* Game::getGrille(void){
	return grille;
}

void Game::setDirectionJoueur(Direction d){

	joueur.direction=d;
	
}

Joueur Game::getJoueur(void){
	return joueur;
}

Fantome Game::getFantome(int no){
	if(no<0 || no>=nbFantome){
		return fantomes[0];
	}
	return fantomes[no];
}

int Game::getNbFantome(void){
	return nbFantome;
}

Game::~Game(void){
	delete fantomes;
	delete grille;
}

bool Game::getLose(void){
	return lose;
}
void Game::start(void){
	begin=true;
}
bool Game::isBegin(void){
	return begin;
}

void Game::refresh(void){
	//init();
	joueur.pos.x = positionInitialPacman.x;
	joueur.pos.y = positionInitialPacman.y;
	lose = false;
	begin = false;
}